package com.feinno.urcs.group.interop.task;

import com.feinno.rpc.channel.RpcFuture;
import com.feinno.rpc.client.RpcMethodStub;
import com.feinno.urcs.group.api.FXLogicPoolService;
import com.feinno.urcs.group.api.FXUserIndexService;
import com.feinno.urcs.group.api.GroupMessageLogService;
import com.feinno.urcs.group.interop.entity.FXCatalogIndex;
import com.feinno.urcs.group.interop.entity.FetionTextMessageArgs;
import com.feinno.urcs.group.siptask.task.GroupTaskEvents;
import com.feinno.urcs.group.util.DateUtils;
import com.feinno.urcs.group.util.MSRPTextMsgParser;
import com.feinno.urcs.group.util.MsrpContent;
import com.feinno.urcs.storage.FileStream;
import com.feinno.urcs.storage.FileStreamService;
import org.helium.framework.annotations.FieldSetter;
import org.helium.framework.annotations.ServiceSetter;
import org.helium.framework.annotations.TaskImplementation;
import org.helium.framework.rpc.LegacyRpcClient;
import org.helium.framework.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;

/**
 * 这个task 的目的是RCS 的文本消息抄送给飞信.
 *
 * @author Li.Hongbo <lihongbo@feinno.com>
 */
@TaskImplementation(event = GroupTaskEvents.GROUP_FETION_MESSAGE_TEXT)
public class FXTextMessageTask implements Task<FetionTextMessageArgs> {
	private static final Logger LOGGER = LoggerFactory.getLogger(FXTextMessageTask.class);
	private String rpcMethodName = "SendMsg";

	@FieldSetter("${FX_GROUP_SERVICE_XML}")
	private LegacyRpcClient rpcClient;
	@ServiceSetter
	private FXLogicPoolService groupLogicPool;
	@ServiceSetter
	private FXUserIndexService fxUserIndexService;
	@ServiceSetter
	private GroupMessageLogService groupMessageLogService;
	@ServiceSetter
	private FileStreamService fileStreamService;

	@Override
	public void processTask(FetionTextMessageArgs args) {
		try {
			FXCatalogIndex fxCatalogIndex = fxUserIndexService.getFXCatalogIndex(args.getGroup().getOperatorMobileNo());
			args.getGroup().setOperatorUid(fxCatalogIndex.getUserId());
			args.getGroup().setOperatorLogicPool(fxCatalogIndex.getLogicalPoolId());


			String fxObjectType = args.getObjectType();

			if ("PHONE_CARD".equals(fxObjectType) || "LOCATION".equals(fxObjectType) || "OUTCE".equals(fxObjectType)) {
				LOGGER.info(String.format("sendToFetion groupId=%s, member=%s , MessageType=%s", args.getGroup().getGroupId(), args.getGroup().getOperatorMobileNo(), fxObjectType));
				if ("LOCATION".equals(fxObjectType)) {
					args.setContentType("text/location");
				} else if ("OUTCE".equals(fxObjectType)) {
					args.setContentType("text/ce");
				} else {
					args.setContentType("text/card");
					byte[] b = downLoadFile(new String(args.getContent()));
					if (b != null) {
						args.setContent(b);
					}
				}
			} else {
				MsrpContent content = new MsrpContent(args.getContent());
				if ("application/vnd.gsma.rcspushlocation+xml".equals(content.getContentType().trim())) {
					args.setContentType("text/location");
					args.setObjectType("LOCATION");

				}  else if ("application/vemoticon+xml".equals(content.getContentType().trim())) {
					args.setContentType("text/out_ce");
					args.setObjectType("OUTCE");
				} else {
					// 普通文本  text/plain
					args.setContentType(content.getContentType());
				}
				args.setContent(MSRPTextMsgParser.getMsrpMsgContent(content).getBytes());
			}

			RpcMethodStub stub = rpcClient.getMethodStub(rpcMethodName);
			RpcFuture future = stub.invoke(args);

			//TODO wait ?
			future.addListener(result -> {
				LOGGER.info(String.format("invoke Fetion RPC Method:%s,retCode=%s,Args=%s", rpcMethodName, result.getValue().getReturnCode(), args.toString()));
				groupMessageLogService.fetionTextMessageDownstreamLog(args, result.getValue().getReturnCode().intValue(), "FXRPC return", DateUtils.getUTCNow());
			});
		} catch (Exception e) {
			LOGGER.error(String.format("process  error,Args=%s", args.toString()), e);
			groupMessageLogService.fetionTextMessageDownstreamLog(args, 500, "FX RPC error", DateUtils.getUTCNow());
		}
	}

	private byte[] downLoadFile(String fileId) throws Exception {
		BufferedInputStream bis = null;
		ByteArrayOutputStream bos = null;
		try {
			FileStream fs = fileStreamService.get(fileId);
			bos = new ByteArrayOutputStream();
			bis = new BufferedInputStream(fs.getInputStream());
			// 建立文件
			if (LOGGER.isInfoEnabled())
				LOGGER.info(String.format("downloading from  fileStreamService id=[ %s ] ", fileId));
			int size = 0;
			byte[] buffer = new byte[1024];
			while ((size = bis.read(buffer)) != -1) {
				bos.write(buffer, 0, size);
			}
			return bos.toByteArray();
		} catch (Exception e) {
			LOGGER.error(String.format(" downloading from  fileStreamService id=[ %s ]", fileId), e);
		} finally {
			bis.close();
		}
		return null;
	}


}
